interface AsyncDelayOptions {
  /**
   * @desc 强制延迟时间。响应时间超出预设延迟时间的部分，如果小于该值则延迟，否则按照其自己的时间来执行
   * @default 300
   */
  delay?: number
  /**
   * @desc 忽略接口延迟时间,响应时间小于该值,则不做延迟
   * @default 200
   */
  ignore?: number
}

/**
 * @desc 接口延迟使用,推荐delay应大于ignore至少200效果为佳
 */
export async function asyncDelay<T>(
  promise: Promise<T>,
  options?: AsyncDelayOptions
) {
  const { delay = 200, ignore = 300 } = options ?? {}
  const start = Date.now()
  return new Promise<T>((resolve, reject) => {
    promise.then(
      (value) => {
        const complate = Date.now()
        const diff = complate - start
        if (diff >= ignore && diff < ignore + delay) {
          const timeout = ignore + delay - diff
          setTimeout(() => {
            resolve(value)
          }, timeout)
        } else {
          resolve(value)
        }
      },
      (err) => {
        const complate = Date.now()
        const diff = complate - start
        if (diff >= ignore && diff < ignore + delay) {
          const timeout = ignore + delay - diff
          setTimeout(() => {
            reject(err)
          }, timeout)
        } else {
          reject(err)
        }
      }
    )
  })
}

export function asyncDelayFactory<
  Params extends Array<object | string | number | boolean | undefined | null>,
  Result
>(fn: (...args: Params) => Promise<Result>, options?: AsyncDelayOptions) {
  return function (...params: Params) {
    const promise = fn(...params)
    return asyncDelay(promise, options)
  }
}
